package org.devocean.groupbuying.web.backend;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.devocean.groupbuying.domain.Article;
import org.devocean.groupbuying.domain.CategoriesLocalization;
import org.devocean.groupbuying.domain.Media;
import org.devocean.groupbuying.domain.Product;
import org.devocean.groupbuying.domain.Tags;
import org.devocean.groupbuying.service.ProductService;
import org.devocean.groupbuying.service.UserService;
import org.devocean.groupbuying.utils.RenderMapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "/gb-cpanel/products")
public class ProductsController {

	@Autowired
	private ProductService productService;

	@Autowired
	private UserService userService;

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public Map<String, ? extends Object> getAllProducts(
			@RequestParam(value = "start", required = false) Integer start,
			@RequestParam(value = "limit", required = false) Integer size) {

		try {

			List<Product> products = productService.getProductsEntries(start,
					size);
			List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
			for (Product product : products) {

				Set<Article> articles = product.getArticlesLocalization()
						.getArticles();
				Iterator<Article> articleIterator = articles.iterator();
				
				while (articleIterator.hasNext()) {
					Article article = articleIterator.next();
					Map<String, Object> data = new ConcurrentHashMap<String, Object>();
					data.put("productID", product.getProductID());
					data.put("articleID", article.getArticleID());
					data.put("title", article.getTitle());
					data.put("al_id", product.getArticlesLocalization()
							.getArticlesLocalizationID());
					data.put("lang", article.getLang());
					data.put("body", article.getBody());
					result.add(data);
				}

			}

			long total = productService.countProducts();
			return RenderMapUtils.getMap(result, total);
		} catch (Exception e) {
			return RenderMapUtils
					.getModelMapError("Error retrieving Merchants from database.");
		}
	}

	@RequestMapping(value = "/", method = RequestMethod.POST)
	public @ResponseBody
	Map<String, ? extends Object> addOrUpdate(@RequestBody Product product,Principal principal) {
	
		try {
			product.getArticlesLocalization()
					.getArticles()
					.iterator().next()
					.setOwner(
							userService.getUserById(Integer.valueOf(principal
									.getName())));
			product.setAvailability(true);
			
			Product newProduct = productService.addOrUpdateProduct(product);
			
			Map<String, Object> data = new ConcurrentHashMap<String, Object>();
			Article article = newProduct.getArticlesLocalization().getArticles().iterator().next();
			data.put("articleID", article.getArticleID());
			data.put("title", article.getTitle());
			data.put("lang", article.getLang());
			data.put("articlesLocalizationID", newProduct.getArticlesLocalization().getArticlesLocalizationID());
			data.put("productID", newProduct.getProductID());
			return RenderMapUtils.getMap(data);
		} catch (Exception e) {
			e.printStackTrace();
			return RenderMapUtils
					.getModelMapError("Error retrieving Articles from database.");
		}

	}

	@RequestMapping(value = "/{articleID}", method = RequestMethod.DELETE)
	public void deleteProduct(@PathVariable("articleID") Integer articleID) {
		productService.removeProduct(articleID);
	}

	@RequestMapping(value="/{articleID}",method=RequestMethod.GET)
	public Map<String, ? extends Object> getArticle(@PathVariable("articleID") Integer articleID){
		
		
		try{
			Product product = productService.getProductByArticleID(articleID);
			return RenderMapUtils.getMap(this.renderProduct(product)) ;
			
		
		}catch (Exception e) {
		return RenderMapUtils
				.getModelMapError("Error retrieving Articles from database.");
	}
	}
	
	@RequestMapping(value = "/localize", method = RequestMethod.GET)
	public Map<String, ? extends Object> localize(Integer LocalizationKey,
			String LocalizationRequest) {
		Product product = productService.getProductByLang(LocalizationKey,LocalizationRequest);
		return RenderMapUtils.getMap(this.renderProduct(product));
	}
	
	public Map<String, Object> renderProduct(Product product){
		
		Integer[] cl_ids = new Integer[product.getArticlesLocalization().getCategoriesLocalizations().size()];
		Integer[] tags_ids = new Integer[product.getArticlesLocalization().getTags().size()];
		Map<String, Object> data = new ConcurrentHashMap<String, Object>();
		if(product.getArticlesLocalization().getArticles()!=null){
			Article article = product.getArticlesLocalization().getArticles().iterator().next();
			data.put("title", article.getTitle());
			data.put("shorte", article.getShorte());
			data.put("body",  article.getBody());
			data.put("articleID", article.getArticleID());
			data.put("lang", article.getLang());
		}
		
		data.put("merchantID", product.getMerchant().getMerchantID());
		data.put("productID", product.getProductID());
		data.put("availability", product.getAvailability());
		data.put("articlesLocalizationID", product.getArticlesLocalization().getArticlesLocalizationID());
		
		int i = 0;
		Iterator<Tags> tagIterator = product.getArticlesLocalization().getTags().iterator();
		
		while (tagIterator.hasNext()) {
			Tags tag = tagIterator.next();
			tags_ids[i++] = tag.getTagsID();
		}
		 i = 0;
		Iterator<CategoriesLocalization> iteratorCategories = product.getArticlesLocalization().getCategoriesLocalizations().iterator();
		while (iteratorCategories.hasNext()) {
			cl_ids[i++] = iteratorCategories.next().getCategoriesLocalizationID();
			
		}
		List<Map<String, Object>> mediaList = new ArrayList<Map<String, Object>>();
		
		for (Media m :	product.getArticlesLocalization().getMediaLocalizations()) {
			Map<String, Object> dataMedia = new ConcurrentHashMap<String, Object>();
			dataMedia.put("mediaID", m.getMediaID());
			dataMedia.put("title", m.getTitle());
			dataMedia.put("media_file_path", m.getMediaFilePath());
			mediaList.add(dataMedia);

		}
		data.put("articlesMedia", mediaList);
		data.put("_categoriesProxy", cl_ids);
		data.put("_tagsProxy", tags_ids);
		return data;
	}
	
	@RequestMapping(value = "/search", method = RequestMethod.GET)
	public Map<String,Object> search(String searchText,
									@RequestParam(value = "start", required = false) Integer start,
									  @RequestParam(value = "limit", required = false) Integer limit) {
		try {
			 
			return productService.search(searchText, new ConcurrentHashMap<String, Object>(3));
			 			
		} catch (Exception e) {
			e.printStackTrace();
			return RenderMapUtils.getModelMapError("No data found!");

		}
	
	}
}
